package com.framework.bdf4j.socket.server;

import java.io.IOException;
import java.nio.charset.Charset;

import javax.annotation.PostConstruct;

import com.framework.bdf4j.socket.coder.LengthFieldBasedFrameDecoder;
import com.framework.bdf4j.socket.coder.MyEncoder;
import com.framework.bdf4j.socket.coder.MyLengthFieldBasedFrameDecoder;
import com.framework.bdf4j.socket.coder.StringDecoder;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;
//https://blog.csdn.net/baidu_34219514/article/details/110440899
public class SocketServer {



    private String port ="8088";

    @PostConstruct
    public void init() {
    	System.out.println("-------启动--------------");
        new Thread(new Runnable() {
            @Override
            public void run() {
                bind();
            }
        }).start();
    }

    private void bind() {
        try {
            EventLoopGroup bossGroup = new NioEventLoopGroup(2); //bossGroup就是parentGroup，是负责处理TCP/IP连接的
            EventLoopGroup workerGroup = new NioEventLoopGroup(100); //workerGroup就是childGroup,是负责处理Channel(通道)的I/O事件

            ServerBootstrap sb = new ServerBootstrap();
            sb.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 128) //初始化服务端可连接队列,指定了队列的大小128
                    .childOption(ChannelOption.SO_KEEPALIVE, false) //短连接
                    .childHandler(new ChannelInitializer<SocketChannel>() {  // 绑定客户端连接时候触发操作
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                        	
                        	
                        	ChannelPipeline pipeline = socketChannel.pipeline();   
                            pipeline.addLast("frameDecoder", new MyLengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 8, 0, 8));    
//                            pipeline.addLast("frameEncoder", new LengthFieldPrepender(8));    
//                            
//                            MyEncoder
                            pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));    
                           pipeline.addLast("encoder", new MyEncoder(CharsetUtil.UTF_8));  
                            
                            //pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));    

                            pipeline.addLast(new MyServerHandler());  

//                            sh.pipeline()
//                            
//                            .addLast(new StringDecoder(Charset.forName("UTF8"))) //解码request
//                            .addLast(new StringEncoder(Charset.forName("UTF8")))
//                            .addLast("frameDecoder", new OwnLengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)) 
//                                        //                 .addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)) 
//
//                                //.addLast(new PackageFrameDecoder())
//                                .addLast("frameEncoder", new LengthFieldPrepender(4)) 
////                                .addLast(new DelimiterBasedFrameDecoder(65535)) 
//                                .addLast(new MyServerHandler()); //使用ServerHandler类来处理接收到的消息
                            
                            
                        }
                    });
            //绑定监听端口，调用sync同步阻塞方法等待绑定操作完
            ChannelFuture future = sb.bind(Integer.parseInt(port)).sync();
            future.channel().closeFuture().sync();
        }catch (Exception e){
       e.printStackTrace();
        }
    }
    
    public static void main(String[] args) throws IOException {
    	new SocketServer().init();
    }
}
